<?php

namespace App\Http\Requests\Api;

use App\Exceptions\Api\ApiInputErrorException;
use App\Exceptions\Api\ApiRsaEecryptErrorException;
use App\Models\User;
use Illuminate\Cache\RedisStore;
use Illuminate\Http\Request;
use App\Services\Rsa;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;


class ApiRequest extends Request
{

    public function __construct(Request $current)
    {
        $files = $current->files->all();

        $files = is_array($files) ? array_filter($files) : $files;

        //是否开启加密模式

        if (config('api.enable_rsa')&&$this->getContent()!=''){
            //获取解密数据
            $content = $this->decryptContent();

            if ($content===false){
                throw new ApiRsaEecryptErrorException('解密失败');
            }

            $contentArray = json_decode($content,true);

            if (is_array($contentArray)){

                $requestData = array_merge($current->request->all(),$contentArray);

            }else{
                $requestData = $current->request->all();
            }

        }else{

            $requestData = $current->request->all();
            $content = $current->getContent();

        }


        $this->setUserResolver($current->getUserResolver());

        $this->setRouteResolver($current->getRouteResolver());

        parent::initialize( $current->query->all(), $requestData, $current->attributes->all(),
            $current->cookies->all(), $files, $current->server->all(), $content);


        $this->setUserResolver($current->getUserResolver());

        $this->setRouteResolver($current->getRouteResolver());

        if ($session = $current->getSession()) {
            $this->setSession($session);
        }

        $session_id = $this->header('session_id');

        //if ($session_id){

            $this->apiSession = new ApiSession($session_id);

            $this->apiUser = new ApiUser($this->apiSession);
        //}


    }

    public function decryptContent(){

        $rsa = new Rsa();

        return $rsa->decrypt($this->getContent());


    }

}


class ApiSession{

    //var $time = 24*3*60;
    var $time = 4320000000;
    var $session_id;

    var $attribute = [];

    public function __construct($session_id)
    {
        //if (!$this->isValidId($session_id)) throw new ApiInputErrorException('session_id 非法');
        if (!$this->isValidId($session_id)) return false;

        $this->session_id = $session_id;

        $this->start();
    }

    function start(){

        $old = Cache::get($this->session_id);

        if (collect($old)->has('_session_id')){
            $data = $old;
        }else{
            $data = ['_session_id'=>$this->session_id];
        }
        Cache::put($this->session_id,$data,$this->time);
        $this->attribute = $data;

    }

    function set($name,$val){
        $data = Cache::get($this->session_id)?Cache::get($this->session_id):[];
        $data = array_merge($data,[$name=>$val]);
        Cache::put($this->session_id,$data,$this->time);
        $this->attribute = $data;
        return true;

    }

    function get($name){

        if (key_exists($name,$this->attribute))
        {
            return $this->attribute[$name];

        }

    }

    function has($name){
        return collect($this->attribute)->get($name)?true:false;

    }

    static function makeToken(){
        return sha1(uniqid('', true).Str::random(25).microtime(true));
    }

    public function destroy(){

        Cache::forget($this->session_id);
    }

    public function isValidId($id)
    {
        return is_string($id) && preg_match('/^[a-f0-9]{40}$/', $id);
    }

}


class ApiUser{

    var $user;

    public function __construct(ApiSession $apiSession)
    {
        $this->apiSession = $apiSession;
    }

    public function login(User $user){

        $this->apiSession->set('user',$user);
        $this->user =  $user;

    }

    public function get(){

        $this->user =  $this->apiSession->get('user');

        return $this->apiSession->get('user');


    }

    public function logout(){
        $this->apiSession->set('user','');
        $this->user ='';
    }

}
